#ifndef __M_BENCH_H__
#define __M_BENCH_H__

#include "../logs/maglog.hpp"
#include <chrono>
#include <algorithm> 
#include <thread>
#include <vector>
#include <iostream>

namespace maglog {

// 压力测试函数：用于测试日志系统在多线程环境下的性能。
// 参数：
// - logger_name: 日志器的名称。
// - thread_num: 线程数量。
// - msglen: 单条日志的长度。
// - msg_count: 日志的总数量。
void bench(const std::string &logger_name, size_t thread_num, size_t msglen, size_t msg_count)
{
    Logger::ptr lp = getLogger(logger_name); // 获取日志器实例
    if (lp == nullptr) return; // 如果日志器不存在，直接返回

    std::string msg(msglen, '1'); // 创建一个指定长度的日志消息
    size_t msg_count_per_thread = msg_count / thread_num; // 计算每个线程处理的日志数量
    size_t remaining_msgs = msg_count % thread_num; // 剩余的日志数量，由最后一个线程处理
    std::vector<double> thread_execution_times(thread_num); // 用于存储每个线程的执行时间
    std::vector<std::thread> threads; // 用于存储线程对象

    // 输出测试的基本信息
    std::cout << "线程数量: " << thread_num << "\n";
    std::cout << "日志总数量: " << msg_count << "\n";
    std::cout << "单条日志大小: " << msglen << " 字节\n";

    auto start_time = std::chrono::high_resolution_clock::now(); // 记录总开始时间
    for (size_t i = 0; i < thread_num; ++i) {
        threads.emplace_back([&, i]() {
            auto start = std::chrono::high_resolution_clock::now(); // 记录线程开始时间
            size_t count = msg_count_per_thread + (i == thread_num - 1 ? remaining_msgs : 0); // 计算当前线程的日志数量
            for (size_t j = 0; j < count; ++j) {
                lp->fatal("%s", msg.c_str()); // 记录日志
            }
            auto end = std::chrono::high_resolution_clock::now(); // 记录线程结束时间
            thread_execution_times[i] = std::chrono::duration<double>(end - start).count(); // 计算线程耗时
        });
    }

    for (auto &thr : threads) {
        thr.join(); // 等待所有线程完成
    }
    auto end_time = std::chrono::high_resolution_clock::now(); // 记录总结束时间
    double total_execution_time = std::chrono::duration<double>(end_time - start_time).count(); // 计算总耗时

    // 找出所有线程中最大耗时
    double max_thread_time = *std::max_element(thread_execution_times.begin(), thread_execution_times.end());

    // 输出性能测试结果
    std::cout << "总耗时: " << total_execution_time << " 秒\n";
    std::cout << "每秒日志数量: " << static_cast<size_t>(msg_count / max_thread_time) << " 条\n";
    std::cout << "每秒日志数据量: " << static_cast<size_t>(msglen * msg_count / max_thread_time / 1024 / 1024) << " MB\n";
}

} // namespace maglog

#endif // __M_BENCH_H__




// #ifndef __M_BENCH_H__
// #define __M_BENCH_H__
// #include "../logs/maglog.h"
// #include <chrono>

// namespace maglog {
// void bench(const std::string &loger_name, size_t thread_num, size_t msglen, size_t msg_count)
// {
//     Logger::ptr lp = getLogger(loger_name);
//     if (lp.get() == nullptr) return;
//     std::string msg(msglen, '1');
//     size_t msg_count_per_thread = msg_count / thread_num;
//     std::vector<double> cost_time(thread_num);
//     std::vector<std::thread> threads;
//     std::cout << "输入线程数量: " << thread_num << std::endl;
//     std::cout << "输出日志数量: " << msg_count << std::endl;
//     std::cout << "输出日志大小: " << msglen * msg_count / 1024  << "KB" << std::endl;
//     for (int i = 0; i < thread_num; i++) {
//         threads.emplace_back([&, i](){
//             auto start = std::chrono::high_resolution_clock::now();
//             for(size_t j = 0; j < msg_count_per_thread; j++) {
//                 lp->fatal("%s", msg.c_str());
//             }
//             auto end = std::chrono::high_resolution_clock::now();
//             auto cost = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
//             cost_time[i] = cost.count();
//             auto avg = msg_count_per_thread / cost_time[i];
//             std::cout << "线程" << i << "耗时: " << cost.count() << "s" << " 平均：" << (size_t)avg << "/s\n";
//         });
//     }
//     for(auto &thr : threads) {
//         thr.join();
//     }
//     double max_cost = 0;
//     for (auto cost : cost_time) max_cost = max_cost < cost ? cost : max_cost;
//     std::cout << "总消耗时间: " << max_cost << std::endl;
//     std::cout << "平均每秒输出: " << (size_t)(msg_count / max_cost) << "条日志" << std::endl;
//     std::cout << "平均每秒输出: " << (size_t)(msglen * msg_count / max_cost / 1024 / 1024) << "MB" << std::endl;
// }
// }

// #endif
